Click here to Skip to main content
15,896,338 members
Please Sign up or sign in to vote.
4.57/5 (4 votes)
See more:
Hello. In my application, i need to automatically scroll. not to caret, but to scroll from the top to the bottom in a smooth effect. same with bottom to top. I will leave all of the complicated stuff out that actually lets the function below work.

C#
private void scrolldown_Click(object sender, EventArgs e)
        {
            t.Enabled = false;
            if (t.Enabled == false)
            {
                t.Enabled = true;
            }
            else t.Enabled = true;
            while (t.Enabled == true)
            {
                scroll(telep.Handle, (speedslider.Value * 2));
            }
        }



scroll(telep.Handle, (speedslider.Value * 2)); needs to be looped. i have tried while(true) but this causes the application do this infinitely many times. this is okay. but when the scroll bar reaches the very bottom of the text box, the app becomes unresponsive. so. what i am trying to do is stop the loop when the scrollbar reaches the very bottom. now, what im about to show you is only PART of the code that causes the above to work.

C#
// Increase posion by pixles
                if (si.nPos < (si.nMax - si.nPage))
                    si.nPos += pixels; //<-- the + can be changed to - for up movement instead of down. si is the SCROLLBARINFO and nPos is its position.
                else
                {
                    ptrWparam = new IntPtr(SB_ENDSCROLL);
                    t.Enabled = false;
                    SendMessage(handle, WM_VSCROLL, ptrWparam, ptrLparam);
                }
Posted
Updated 19-Feb-11 19:14pm
v3

In addition to SA's response, you should not do a loop in your main thread. That will freeze up your UI. You need to do tasks like this in a background thread so your main UI will remain responsive. You can use BackgroundWorker for this (look it up on MSDN).
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 20-Feb-11 0:03am    
I trust did not mind arguably fast loops, which are quite find and usually unavoidable...
My 5 anyway,
--SA
Espen Harlinn 6-Apr-11 16:09pm    
Good point :)
Having done a number of controls over the years, I've always found that the best, and smoothest, way to handle the scrollbar operations is to just to move the contents already painted - if anything you've already painted will be visible after scrilling; and then invalidate the rest of the window.

In other words you have to keep track of what's visible and painted.

The native windows API provides a nice function:
BOOL ScrollDC( HDC hDC,
    int dx,
    int dy,
    const RECT *lprcScroll,
    const RECT *lprcClip,
    HRGN hrgnUpdate,
    LPRECT lprcUpdate
);

That efficiently moves what you've already painted - Documented here[^]

I'd start out by just invalidating the window, and enhance the implementation to reuse what's painted when you've got that part working.

Regards
Espen Harlinn
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 6-Apr-11 19:02pm    
Agree. This is an important point, in fact. My 5.
--SA
Espen Harlinn 8-Apr-11 3:44am    
Thanks, SAKryukov!
Vlad, for a programmer, there is not such thing as "crashing". You should use debugger properly and, in order to post a correct Question for a CodeProject, learn how to dump exception information.

Spotting this particular problem based on your posted code is a bit tedious and boring. We could do little better. Let me help you a bit with System.Windows.Forms specific exception handling feature which many developers miss; so it will help you in future as well (and please forgive me if you already know that). Most likely, all your problem unfolds in you UI thread. This is what you have to do first.

In your entry point function (usually called Program.Main), add the following line (assuming "using System.Windows.Forms;"):

C#
[System.STAThread]
static void Main() {
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    //...
} //Main


Add some handler of the special Application event fired on exception inside of main loop if Application.Run. This code should be called before you show your main form, as soon as possible, for example, in its constructor:

C#
Application.ThreadException += delegate(
    object sender,
    System.Threading.ThreadExceptionEventArgs eventArgs) {
        System.Windows.Forms.MessageBox.Show(
            string.Format(
                "{0}: \n\n{1}",
                eventArgs.Exception.GetType().Name,
                eventArgs.Exception.Message),
            string.Format(" {0}: Error", Application.ProductName),
            MessageBoxButtons.OK, MessageBoxIcon.Error);
}; //Application.ThreadException


If your Framework version is 3.5 or later, lambda form is more convenient:

C#
Application.ThreadException += (sender, eventArgs) => {
   //...
}; //Application.ThreadException


This will show all your exceptions in UI thread without termination of the application, you also can effectively use debugger break point in this function.

[EDIT]
Additionally or alternatively, handle the events System.AppDomain.UnhandledException and System.AppDomain.FirstChanceException.
My credit to Espen Harlinn for the idea.
[END EDIT]

If it does not provide enough information, add detailed dump: exception stack (first thing to do) and possibly all inner exceptions, recursively. If you want help from CodeProject, save this dump in file and post its content in your Question (please, try to format nicely!).

If your problem is still not resolved, ask follow-up questions, but please not post it as an Answer (important!); use "Improve question" or "Add comment".

By the way, I did not understand why you use P/Invoke, that is, why pure .NET API was not enough?

—SA
 
Share this answer
 
v5
Comments
Sandeep Mewara 19-Feb-11 23:55pm    
Good answer, my 5!
Don't know who gave a 3... :doh:
Sergey Alexandrovich Kryukov 20-Feb-11 0:03am    
Thank you, Sandeep.
These days somebody does is often. Who called them "univoters"?
--SA
MCY 20-Feb-11 5:15am    
nice. 5!
Sergey Alexandrovich Kryukov 20-Feb-11 13:17pm    
Thank you.
--SA
RaviRanjanKr 6-Apr-11 15:20pm    
Nice Answer! My 5 :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900